<template>
  <div class="app-container ">
    <FilterSearch class="filter-search" :value="queryParams" :config="configData">
    </FilterSearch>
    <div class="main">
      <div class="table">
        <el-table v-loading="tableData.loading" :data="tableData.rows" @selection-change="handleSelectionChange">
          <el-table-column type="selection" minWidth="55" align="center" />
          <el-table-column type="index" label="序号" minWidth="60">
            <template #default="scope">
              {{ scope.$index + 1 }}
            </template>
          </el-table-column>
          <el-table-column label="角色名称" prop="roleName" minWidth="120" :show-overflow-tooltip="true" />
          <el-table-column prop="roleSort" label="排序" minWidth="80" sortable></el-table-column>
          <el-table-column label="权限字符" prop="roleKey" minWidth="160" :show-overflow-tooltip="true" />
          <el-table-column label="状态" align="center" prop="status" minWidth="80">
            <template #default="scope">
              <dict-tag :options="statusOptions" :value="scope.row.status"></dict-tag>
            </template>
          </el-table-column>
          <el-table-column label="备注" align="center" prop="remark" minWidth="200" :show-overflow-tooltip="true">
          </el-table-column>
          <el-table-column label="创建时间" align="center" sortable prop="createTime" minWidth="180">
          </el-table-column>
          <el-table-column label="更新时间" align="center" sortable prop="updateTime" minWidth="180">
          </el-table-column>
          <el-table-column label="操作" fixed="right" align="center" minWidth="160"
            class-name="small-padding fixed-width">
            <template #default="scope">
              <el-button size="mini" type="text" icon="el-icon-edit" @click="handleEdit(scope.row)"
                v-hasPermi="['permission:role:edit']">编辑</el-button>
              <el-button size="mini" type="text" icon="el-icon-delete" @click="handleRemove(scope.row)"
                v-hasPermi="['permission:role:remove']">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="page">
        <Pagination :total="tableData.total" :page="queryParams.pageNum" :limit="queryParams.pageSize"
          @pagination="getList" />
      </div>
    </div>

    <!-- 添加或编辑角色配置对话框 -->
    <el-dialog :title="formInline.title" v-model="formInline.diaVis" width="680px" :close-on-click-modal="false">
      <el-form ref="formRef" :model="formInline.form" :rules="rules" label-width="100px">
        <el-row>
          <el-col :span="12">
            <el-form-item label="角色名称" prop="roleName">
              <el-input v-model="formInline.form.roleName" clearable placeholder="请输入角色名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="权限字符">
              <el-input v-model="formInline.form.roleKey" clearable placeholder="请输入权限字符" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="角色顺序">
              <el-input-number v-model="formInline.form.roleSort" controls-position="right" :min="0" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="状态">
              <el-radio-group v-model="formInline.form.status">
                <el-radio :label="item.value" v-for="(item, index) in statusOptions" :key="index">{{ item.label
                }}</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="菜单权限">
              <el-checkbox v-model="formInline.menuExpand"
                @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>
              <el-checkbox v-model="formInline.menuNodeAll"
                @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
              <el-checkbox v-model="formInline.menuCheckStrictly"
                @change="handleCheckedTreeConnect($event, 'menu')">父子联动</el-checkbox>
              <el-scrollbar style="width:100%;height:300px;">
                <div>
                  <el-tree class="tree-border" :props="{ label: 'menuName', children: 'children' }"
                    :data="formList.menuTreeOptions" show-checkbox ref="menuTreeRef" node-key="menuId"
                    :check-strictly="!formInline.menuCheckStrictly" empty-text="加载中，请稍候"></el-tree>
                </div>
              </el-scrollbar>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="备注">
              <el-input v-model="formInline.form.remark" rows="3" resize="none" type="textarea"
                placeholder="请输入内容"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { computed, onMounted, ref } from 'vue';
import { handleTree } from "@/utils/ruoyi";
import { roleList, roleAdd, roleEdit, roleRemove } from "@/api/permission/role";
import { menuList } from "@/api/system/menu";
import { statusOptions } from "@/constant";

const { proxy } = getCurrentInstance();
const menuTreeRef = ref(null);
const formRef = ref(null);
const queryParams = ref({
  roleName: "",
  roleKey: null,
  status: null,
  createTime: [],
  pageNum: 1,
  pageSize: 10
});
const handleChecked = ref({
  ids: [],
  multiple: true
})
const tableData = reactive({
  rows: [],
  total: 1,
  loading: false
});
const formInline = reactive({
  form: {
    id: null,
    roleId: null,
    roleName: null,
    roleKey: null,
    roleSort: 0,
    status: 1,
    menuIds: [],
    remark: null
  },
  title: "新增",
  diaVis: false,
  menuExpand: false,
  menuNodeAll: false,
  menuCheckStrictly: true
});
const formList = reactive({
  menuTreeOptions: []
});
const configData = computed(() => {
  let config = {
    itemConfig: [
      {
        type: "input",
        prop: "roleName",
        label: "角色名称",
        placeholder: "请输入"
      },
      {
        type: "input",
        prop: "roleKey",
        label: "权限字符",
        placeholder: "请输入"
      },
      {
        type: "select",
        prop: "status",
        label: "状态",
        placeholder: "请选择",
        optList: statusOptions
      },
      {
        type: "datetimerange",
        prop: "createTime",
        label: "创建时间",
        dateFormate: "YYYY-MM-DD HH:mm:ss",
        placeholder: "请选择"
      },
    ],
    operate: [
      {
        icon: "Search",
        type: "primary",
        name: "查询",
        handleClick: getLoad,
        rule: false,
      },
      {
        icon: "RefreshRight",
        type: "info",
        name: "重置",
        handleClick: reset,
        rule: false,
      },
      {
        icon: "Plus",
        type: "success",
        name: "新增",
        handleClick: insert,
        rule: false,
        disabled: !proxy.$auth.hasPermi("permission:role:add")
      },
      {
        icon: "Delete",
        type: "danger",
        name: "删除",
        handleClick: remove,
        rule: false,
        disabled: handleChecked.value.multiple
      }
    ],
    rules: {},
  };
  return config;
});
const rules = computed(() => {
  let rules = {
    roleName: [
      { required: true, message: "请输入角色名称", trigger: "blur" },
      { min: 2, max: 20, message: "长度在 2 到 20 个字符", trigger: "blur" }
    ]
  };
  return rules;
});
function handleSelectionChange(selection) {
  handleChecked.value.ids = selection.map(item => item.id);
  if (handleChecked.value.ids.length > 0) {
    if (proxy.$auth.hasPermi("permission:role:edit")) {
      handleChecked.value.multiple = false
    }
  } else {
    handleChecked.value.multiple = true;
  }
};

// 树权限（展开/折叠）
function handleCheckedTreeExpand(val) {
  let treeList = formList.menuTreeOptions;
  for (let i = 0; i < treeList.length; i++) {
    menuTreeRef.value.store.nodesMap[treeList[i].menuId].expanded = val;
  }
};
// 树权限（全选/全不选）
function handleCheckedTreeNodeAll(val) {
  menuTreeRef.value.setCheckedNodes(val ? formList.menuTreeOptions : [])
};

/** 树权限（父子联动） */
function handleCheckedTreeConnect(value) {
  formInline.menuCheckStrictly = value ? true : false;
}
function getMenuAllCheckedKeys() {
  // 目前被选中的菜单节点
  let checkedKeys = menuTreeRef.value.getCheckedKeys()
  // 半选中的菜单节点
  let halfCheckedKeys = menuTreeRef.value.getHalfCheckedKeys()
  checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
  return checkedKeys
};
function insert() {
  formInline.title = "新增";
  formInline.diaVis = true;
};
function handleEdit(row) {
  formInline.form = {
    id: row.id,
    roleId: row.roleId,
    roleName: row.roleName,
    roleKey: row.roleKey,
    roleSort: row.roleSort,
    status: row.status,
    menuIds: row.menuIds,
    remark: row.remark
  };
  formInline.diaVis = true;
  formInline.title = "编辑";
  row.menuIds.forEach(async (v) => {
    await nextTick();
    menuTreeRef.value.setChecked(v, true)
  })
};
function submitForm() {
  formRef.value.validate(valid => {
    if (valid) {
      formInline.form.menuIds = getMenuAllCheckedKeys();
      if (formInline.title == "新增") {
        roleAdd(formInline.form).then(res => {
          if (res.code == 200) {
            cancel();
            getLoad();
          }
        });
      } else {
        roleEdit(formInline.form).then(res => {
          if (res.code == 200) {
            cancel();
            getLoad();
          }
        });
      }
    };
  })
};
function handleRemove(row) {
  proxy.$modal.confirm('是否确认删除角色名称为"' + row.roleName + '"的数据项？').then(() => {
    roleRemove([row.id]).then(res => {
      getLoad();
    });
  });
}
function remove() {
  proxy.$modal.confirm('是否确认删除编号为"' + handleChecked.value.ids + '"的数据项？').then(() => {
    roleRemove(handleChecked.value.ids).then(res => {
      getLoad();
    });
  });
}
function getList(page) {
  queryParams.value.pageNum = page.page;
  queryParams.value.pageSize = page.limit;
  getLoad();
}

function getLoad() {
  tableData.loading = true;
  roleList(queryParams.value).then(res => {
    tableData.rows = res.data.rows;
    tableData.total = res.data.total;
    tableData.loading = false;
  });
};
function getOptions() {
  menuList().then(res => {
    formList.menuTreeOptions = handleTree(res.data, "menuId");
  });
}
function cancel() {
  menuTreeRef.value.setCheckedNodes([])
  formRef.value.resetFields();
  formInline.form = {
    id: null,
    roleId: null,
    roleName: null,
    roleKey: null,
    roleSort: 0,
    status: 1,
    menuIds: [],
    remark: null
  }
  formInline.title = "新增";
  formInline.diaVis = false;
  formInline.menuExpand = false;
  formInline.menuNodeAll = false;
  formInline.menuCheckStrictly = true;
}
function reset() {
  queryParams.value = {
    roleName: "",
    roleKey: null,
    status: null,
    createTime: [],
    pageNum: 1,
    pageSize: 10
  }
  getLoad();
};
onMounted(() => {
  getLoad();
  getOptions();
});
</script>